﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace BeamModule.SplitBream
{
	internal class NewInterruptBream
	{
		public NewInterruptBream(List<SplitBreamInfo> m_lstInfo, FamilyInstance item, ExternalCommandData commandData)
		{
			this.m_commandData = commandData;
			this.m_uiDoc = commandData.Application.ActiveUIDocument;
			this.m_doc = this.m_uiDoc.Document;
			this.m_lstSplitBreamInfo = m_lstInfo;
			this.m_bream = item;
			this.m_breamLocation = ((item.Location as LocationCurve).Curve as Line);
		}

		public void GetNewBreams()
		{
			this.CancelOldBreamJudge(this.GetOldBreamJudge());
			this.CreateBream();
			this.CreateTempBream();
			this.ComparBeforeCommitLocationToLaterCommitLocation();
			this.DeleteNoUseBream();
			this.CreateLoactionErrBream();
			this.DeletaTempBream();
			this.NewBreamJudgeElement();
		}

		public void CreateTempBream()
		{
			Transaction transaction = new Transaction(this.m_doc, "CreateTempBream");
			transaction.Start();
			try
			{
				ICollection<ElementId> collection = new List<ElementId>();
				collection = ElementTransformUtils.CopyElement(this.m_doc, this.m_bream.Id, new XYZ(10.0, 10.0, 0.0));
				FamilyInstance familyInstance = null;
				IEnumerator<ElementId> enumerator = collection.GetEnumerator();
				{
					if (enumerator.MoveNext())
					{
						ElementId elementId = enumerator.Current;
						familyInstance = (this.m_doc.GetElement(elementId) as FamilyInstance);
					}
				}
				LocationCurve locationCurve = familyInstance.Location as LocationCurve;
				double z = this.m_breamLocation.GetEndPoint(0).Z;
				Curve curve = Line.CreateBound(new XYZ(55.0, 55.0, z), new XYZ(65.0, 65.0, z));
				locationCurve.Curve = curve;
				transaction.Commit();
				this.m_tempBream = familyInstance;
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		public void CreateBream()
		{
			for (int i = 0; i < this.m_lstSplitBreamInfo.Count - 1; i++)
			{
				Transaction transaction = new Transaction(this.m_doc, "CreateBream");
				transaction.Start();
				try
				{
					ICollection<ElementId> collection = new List<ElementId>();
					collection = ElementTransformUtils.CopyElement(this.m_doc, this.m_bream.Id, new XYZ((double)i, (double)i, 0.0));
					FamilyInstance familyInstance = null;
					IEnumerator<ElementId> enumerator = collection.GetEnumerator();
					{
						if (enumerator.MoveNext())
						{
							ElementId elementId = enumerator.Current;
							familyInstance = (this.m_doc.GetElement(elementId) as FamilyInstance);
						}
					}
					LocationCurve locationCurve = familyInstance.Location as LocationCurve;
					Curve curve = Line.CreateBound(this.m_lstSplitBreamInfo[i].m_splitPoint, this.m_lstSplitBreamInfo[i + 1].m_splitPoint);
					locationCurve.Curve = curve;
					this.m_beforeCommitLocation.Add(familyInstance, curve as Line);
					transaction.Commit();
					this.m_laterCommitLocation.Add(familyInstance, (familyInstance.Location as LocationCurve).Curve as Line);
					this.m_newBream.Add(familyInstance);
				}
				catch (Exception)
				{
					transaction.RollBack();
				}
			}
		}

		public void ComparBeforeCommitLocationToLaterCommitLocation()
		{
			foreach (KeyValuePair<Element, Line> keyValuePair in this.m_beforeCommitLocation)
			{
				if (!this.EqualBreamLocation(keyValuePair.Value, this.m_laterCommitLocation[keyValuePair.Key]))
				{
					this.m_locationErrOfBream.Add(keyValuePair.Key, keyValuePair.Value);
					this.m_newBream.Remove(keyValuePair.Key);
				}
			}
		}

		private bool EqualBreamLocation(Curve oneCurve, Curve twoCurve)
		{
			bool result = false;
			XYZ endPoint = oneCurve.GetEndPoint(0);
			XYZ endPoint2 = oneCurve.GetEndPoint(1);
			XYZ endPoint3 = twoCurve.GetEndPoint(0);
			XYZ endPoint4 = twoCurve.GetEndPoint(1);
			if (NewInterruptBream.EqualBreamPoint(endPoint, endPoint3) && NewInterruptBream.EqualBreamPoint(endPoint2, endPoint4))
			{
				result = true;
			}
			return result;
		}

		private void CreateLoactionErrBream()
		{
			foreach (KeyValuePair<Element, Line> keyValuePair in this.m_locationErrOfBream)
			{
				Transaction transaction = new Transaction(this.m_doc, "CreateLoactionErrBream");
				transaction.Start();
				try
				{
					ICollection<ElementId> collection = new List<ElementId>();
					collection = ElementTransformUtils.CopyElement(this.m_doc, this.m_tempBream.Id, XYZ.Zero);
					FamilyInstance familyInstance = null;
					IEnumerator<ElementId> enumerator2 = collection.GetEnumerator();
					{
						if (enumerator2.MoveNext())
						{
							ElementId elementId = enumerator2.Current;
							familyInstance = (this.m_doc.GetElement(elementId) as FamilyInstance);
						}
					}
					LocationCurve locationCurve = familyInstance.Location as LocationCurve;
					locationCurve.Curve = keyValuePair.Value;
					transaction.Commit();
					this.m_newBream.Add(familyInstance);
				}
				catch (Exception)
				{
					transaction.RollBack();
				}
			}
		}

		private void DeleteNoUseBream()
		{
			Transaction transaction = new Transaction(this.m_doc, "DeleteNoUseBream");
			transaction.Start();
			try
			{
				foreach (KeyValuePair<Element, Line> keyValuePair in this.m_locationErrOfBream)
				{
					this.m_doc.Delete(keyValuePair.Key.Id);
				}
				this.m_doc.Delete(this.m_bream.Id);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private void DeletaTempBream()
		{
			Transaction transaction = new Transaction(this.m_doc, "DeletaTempBream");
			transaction.Start();
			try
			{
				this.m_doc.Delete(this.m_tempBream.Id);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private List<Element> GetOldBreamJudge()
		{
			List<Element> list = new List<Element>();
			ICollection<ElementId> collection = new List<ElementId>();
			collection = JoinGeometryUtils.GetJoinedElements(this.m_doc, this.m_bream);
			foreach (ElementId elementId in collection)
			{
				list.Add(this.m_doc.GetElement(elementId));
			}
			return list;
		}

		private void CancelOldBreamJudge(List<Element> lstJudgeElement)
		{
			foreach (Element element in lstJudgeElement)
			{
				Transaction transaction = new Transaction(this.m_doc, "CancelOldBreamJudge");
				transaction.Start();
				try
				{
					JoinGeometryUtils.UnjoinGeometry(this.m_doc, this.m_bream, element);
					transaction.Commit();
				}
				catch (Exception)
				{
					transaction.RollBack();
				}
			}
		}

		private void NewBreamJudgeElement()
		{
			foreach (Element element in this.m_newBream)
			{
				foreach (SplitBreamInfo splitBreamInfo in this.m_lstSplitBreamInfo)
				{
					if (splitBreamInfo.m_splitElement != null)
					{
						XYZ endPoint = (element.Location as LocationCurve).Curve.GetEndPoint(0);
						XYZ endPoint2 = (element.Location as LocationCurve).Curve.GetEndPoint(1);
						if (NewInterruptBream.EqualBreamPoint(endPoint, splitBreamInfo.m_splitPoint) || NewInterruptBream.EqualBreamPoint(endPoint2, splitBreamInfo.m_splitPoint))
						{
							this.JudgeElemmt(element, splitBreamInfo.m_splitElement);
						}
					}
				}
			}
		}

		private static bool EqualBreamPoint(XYZ one, XYZ two)
		{
			return Math.Abs(one.X - two.X) < 0.5 && Math.Abs(one.Y - two.Y) < 0.5 && Math.Abs(one.Z - two.Z) < 0.5;
		}

		private void JudgeElemmt(Element one, Element two)
		{
			Transaction transaction = new Transaction(this.m_doc, "CancelOldBreamJudge");
			transaction.Start();
			try
			{
				if (!JoinGeometryUtils.AreElementsJoined(this.m_doc, one, two) && !JoinGeometryUtils.AreElementsJoined(this.m_doc, two, one))
				{
					JoinGeometryUtils.JoinGeometry(this.m_doc, one, two);
				}
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
			}
		}

		private const double POINTERREQUAL = 0.5;

		private List<SplitBreamInfo> m_lstSplitBreamInfo;

		private Line m_breamLocation;

		private FamilyInstance m_bream;

		private FamilyInstance m_tempBream;

		private Dictionary<Element, Line> m_beforeCommitLocation = new Dictionary<Element, Line>();

		private Dictionary<Element, Line> m_laterCommitLocation = new Dictionary<Element, Line>();

		private Dictionary<Element, Line> m_locationErrOfBream = new Dictionary<Element, Line>();

		private List<Element> m_newBream = new List<Element>();

		private ExternalCommandData m_commandData;

		private UIDocument m_uiDoc;

		private Document m_doc;
	}
}
